home *** CD-ROM | disk | FTP | other *** search
- /* Copyright, 1990, Regents of the University of Colorado */
- #define then /**/
- #define NULL 0
- #include <stdio.h>
- #include "../inc/D_lib.h"
- #include "../inc/internal.h"
-
- /* routing module
-
- consists of the following exported functions
- D_route_tree_init - initialize routing for tree patterns
- D_route_tree - compute routing for tree patterns
- D_route_cube_init initialize routing for hypercube or butterfly routing
- D_route_cube - compute routing for hypercube routing
-
- */
-
- /* imports the following data structures */
-
- static ginv(n)
- int n;
-
- /*
-
- ginv = inverse of gray function
-
- answers the inevitable question, what task is being
- carried out on node n?
- */
-
- {
- int i, t;
- t = n/2;
- i = n;
- while(t != 0)
- {
- i = i^t;
- t = t/2;
- }
- return(i);
- }
-
- int D_gray(index, entry)
- int index;
- D_env_tbl *entry;
- {
- int i;
- int prod=1, sum=0;
- int mid = 0;
-
- for (i=0; i<entry->n_dims; i++)
- {
- prod <<= entry->mach_dim[i];
- sum += entry->mach_dim[i];
- }
- for (i=0; i<entry->n_dims; i++)
- {
- int t;
- sum -= entry->mach_dim[i];
- prod >>= entry->mach_dim[i];
- t = (index >> sum);
- mid += (t^(t/2));
- mid *= prod;
- index ^= t<<sum;
- }
- return mid;
- }
-
- int D_ginv(index, entry)
- int index;
- D_env_tbl *entry;
- {
- int i;
- int prod=1, sum=0;
- int mid = 0;
-
- for (i=0; i<entry->n_dims; i++)
- {
- prod <<= entry->mach_dim[i];
- sum += entry->mach_dim[i];
- }
- for (i=0; i<entry->n_dims; i++)
- {
- int t;
- sum -= entry->mach_dim[i];
- prod >>= entry->mach_dim[i];
- t = (index >> sum);
- mid += ginv(t);
- mid *= prod;
- index ^= t<<sum;
- }
- return mid;
- }
-
- /* D_find_parent
- *
- * Purpose : find parent of this node
- *
- * Input : index of env, mask of first parent, bitmap, number of root
- *
- * Output : parent id
- */
- int D_find_parent(index, mask, bitmap, root)
- int index,mask,root;
- D_BOOL bitmap[];
- {
- while ((mask > 0) && !(bitmap[index ^ mask])){
- index ^= mask;
- mask >>=1;
- }
- return (mask != 0)?
- index ^ mask:
- root;
- }
-
-
- /* D_set_stack
- *
- * Purpose : determine all children this env will send to
- *
- * Input : bitmap, index of env to check, size of envstructure, current bit,
- * if this node must handle the node 0's children also
- *
- * Output : stack (a bitmap) has all the nodes which index will send to set,
- * this returns if there are any children
- */
- D_BOOL D_set_stack(bitmap, stack, index, size, mask, do_root)
- D_BOOL bitmap[];
- D_BOOL stack[];
- int index;
- int size;
- int mask;
- D_BOOL do_root;
- {
- int t;
- D_BOOL res = FALSE;
-
- if (do_root){
- res = D_set_stack(bitmap, stack, 0, size, 1, FALSE);
- stack[index] = 0;
- }
- for (; (t = mask^index) < size; mask <<= 1)
- if (bitmap[t])
- then{
- res =1;
- stack[t] = 1;
- }
- else{
- D_BOOL tres = D_set_stack(bitmap,stack,t, size, mask<<1, FALSE);
- res = res || tres;
- }
- return res;
- }
-
- /* D_grand_children
- *
- * Purpose : determine all children below a certain child
- *
- * Input : bitmap, if the bitmap should not be used, where to put the
- * results, index of env to check (processor number!),
- * size of envstructure, current bit,
- * if this node must handle the node 0's children also,
- * entry into env_table
- *
- * Output : stack (a bitmap) has all the nodes which index will send to set,
- * this returns pointer to next stack location
- */
- short int *D_grand_children(
- bitmap, implicit, stack, index, size, mask,do_root,entry)
- D_BOOL bitmap[];
- D_BOOL implicit;
- short int *stack;
- int index;
- int size;
- int mask;
- D_BOOL do_root;
- D_env_tbl *entry;
- {
- int vmach, /*machine processor number*/
- proc; /*index into environment structure*/
-
- if (do_root){
- stack = D_grand_children(
- bitmap, implicit, stack, 0, size, 1, FALSE,entry);
- }
- vmach = mask^index;
- proc = D_ginv(vmach,entry);
- while (proc<size){
- if (implicit?1:bitmap[vmach])
- then{
- *stack = proc;
- stack = D_grand_children(
- bitmap,implicit,++stack,vmach,size, mask<<1, FALSE,entry);
- }
- else{
- stack = D_grand_children(
- bitmap,implicit,++stack,vmach, size, mask<<1, FALSE,entry);
- }
- mask <<=1;
- vmach = mask^index;
- proc = D_ginv(vmach,entry);
- }
- return stack;
- }
-
-
-
- /* D_high_bit
- *
- * Purpose : find highest bit set in an int
- *
- * Input : int
- *
- * Output : everything but the highest bit masked off
- *
- */
- int D_high_bit(x)
- int x;
- {
- register unsigned int i = 1 << (8*sizeof(int) - 2);
- for(;(i>0) && !(i&x); i=i >> 1);
- return i;
- };
-
- int which_bit(x)
- unsigned int x;
- {
- int count=0;
- for (;x>0;x=x >> 1) count++;
- if (count>0) count--;
- return(count);
- };
-
-
-
- /* static values for tree routing */
- static D_BOOL pt_pt;
- static envvar child, parent;
- static int child_que; /*next child to send out*/
- static D_BOOL is_root;
- static int next_child; /*bit mask of bit to be flipped*/
- static int stack_crnt;
- static my_gray;
-
- /* D_route_tree_init
- *
- * Purpose : initialize tree routing
- *
- * Input : env - pointer to an envset (there can only be one envset)
- * off_parent - parent env if not on this structure
- *
- * Output : if this is root of tree then off_parent else parent of this node
- */
- envvar *D_route_tree_init(env, done, off_parent)
- D_env_set *env;
- D_BOOL *done;
- envvar *off_parent;
- {
- my_gray = D_gray(D_my_env.index, &D_env_table[D_my_env.name]);
- /*compute pt_pt*/
- if (D_my_env.name != env->name)
- pt_pt = TRUE;
- else if ((env->count != 1) ||
- ((env->implicit) && (D_env_table[env->name].size>1)))
- pt_pt = FALSE;
- else{
- if (env->implicit)
- pt_pt = FALSE;
- else{
- register int sum = 0;
- register D_BOOL *pt = env->bitmap;
- D_BOOL *last = &(env->bitmap[D_env_table[env->name].size-1]);
- for (; pt <=last; pt++)
- sum += *pt;
- pt_pt = (sum == 1);
- }
- }
-
- if (pt_pt){
- child.name = env->name;
- if (env->implicit)
- then child.index = 0;
- else{
- register D_BOOL *p = env->bitmap;
- for (;*p!=1;p++);
- child.index = D_ginv(p - env->bitmap, &D_env_table[env->name]);
- }
- *done = FALSE;
- return off_parent;
- }
- else{
- register int high_me;
- int size;
- int root = 0;
- unsigned int virtual_dim;
- D_BOOL is_child;
-
- size = D_env_table[D_my_env.name].size;
- virtual_dim = D_high_bit(size);
- virtual_dim =(size & ~virtual_dim)?(virtual_dim<<1):virtual_dim;
- high_me = D_high_bit(my_gray);
-
- /*determine if this is root of tree*/
- if ((env->name != D_my_env.name) ||
- (env->implicit && (my_gray == 0)))
- then is_root = TRUE;
- else if(env->implicit)
- then is_root= FALSE;
- else{
- register D_BOOL *p,
- *stop = &(env->bitmap[my_gray]);
- is_root = TRUE;
- for (p=env->bitmap; p<stop; p++)
- if (*p){
- is_root = FALSE;
- root = p - env->bitmap;
- break;}
- }
-
- /*compute who to send to*/
- if (!env->implicit && (env->name == D_my_env.name))
- {
- register int i;
- for (i=0; i<size; i++)
- D_route_stack[i] = 0;
- is_child = D_set_stack(
- env->bitmap, D_route_stack,
- my_gray, size,
- (high_me == 0? 1 : high_me<<1),
- is_root&& my_gray!=0);
- stack_crnt = my_gray;
- if(is_child)
- then{
- child.name = D_my_env.name;
- for (; stack_crnt<size && !D_route_stack[stack_crnt];
- stack_crnt++);
- *done = stack_crnt == size;
- child_que = stack_crnt++;
- }
- else *done = TRUE;
-
- }
- else if(env->implicit && (env->name == D_my_env.name))
- {
- child.name = D_my_env.name;
- next_child =
- high_me ?
- high_me << 1 :
- 1;
- child_que = my_gray ^ next_child;
- *done = (D_ginv(child_que, &D_env_table[env->name]) >= size);
- next_child <<= 1;
- }
- else
- { /*find first non zero env to send to*/
- child.name = env->name;
- if (env->implicit)
- then {
- child_que = 0;
- *done = FALSE;
- }
- else {
- for (child_que=0;
- child_que<size && (env->bitmap[child_que] == 0);
- child_que++);
- *done = !env->bitmap[child_que];
- }
- }
-
- /*compute parent (if there is one)*/
- if (is_root)
- return off_parent;
- else{
- parent.name = D_my_env.name;
- parent.index = (env->implicit) ?
- high_me ^ my_gray :
- D_find_parent(my_gray, high_me, env->bitmap, root);
- parent.index = D_ginv(parent.index, &D_env_table[env->name]);
- return &parent;
- }
- }
- }
-
- /* D_route_tree
- *
- * Purpose : tree routing
- *
- * Input : env - pointer to an envset
- * done - flag to return if there are no children
- *
- * Output : pointer to child envvar,
- * done - set true if there are no more children after this
- */
- envvar *D_route_tree(env, done, children)
- D_env_set *env;
- D_BOOL *done;
- short int **children;
- {
- if (pt_pt){
-
- *done = TRUE;
- *children = D_route_children;
- if (env->name != D_my_env.name)
- then {
- int child_high = D_high_bit(child_que);
- short int *end;
-
- end = D_grand_children(
- env->bitmap, env->implicit,D_route_children,
- child_que, D_env_table[env->name].size,
- (child_high==0)?1:(child_high<<1),FALSE,
- &D_env_table[env->name]);
- *end = -1;
- }
- else D_route_children[0] = -1;
- }
- else {
- int size = D_env_table[D_my_env.name].size;
- int child_high = D_high_bit(child_que);
- short int *end;
-
- child.index = D_ginv(child_que, &D_env_table[env->name]);
- *children = D_route_children;
- D_route_children[0] = -1;
- end = D_grand_children(
- env->bitmap,env->implicit,D_route_children,
- child_que,size,child_high<<1,FALSE,
- &D_env_table[env->name]);
- *end = -1;
- if (env->implicit){
- child_que = my_gray ^ next_child;
- *done = D_ginv(child_que, &D_env_table[env->name]) >= size;
- next_child <<=1;
- }
- else{
- for (; stack_crnt < size && !D_route_stack[stack_crnt];
- stack_crnt++);
- *done = (stack_crnt == size) || env->name != D_my_env.name;
- child_que = stack_crnt++;
- }
- }
- return &child;
- }
-
-
-
- /*static values for cube routing */
-
- static D_BOOL is_simple_cube;
- static D_BOOL is_stack_empty;
- static D_env_set *my_set, *crnt_set;
- static int crnt_index;
- static D_BOOL done_me;
- static int my_root;
- static int bit; /*bit currently flipping*/
- static unsigned int maxstep;
- static int size,done_size;
-
- static int D_parent(target, next, parent, logtarget, my_set,env,size)
- int target, next, *parent, *logtarget;
- D_env_set *my_set;
- D_env_set *env;
- int size;
- {
- int pfound, neigh;
-
- pfound = FALSE;
- for(neigh=1; neigh<next && !pfound; neigh<<=1){
- *logtarget = D_ginv(
- *parent = (target^neigh),
- &D_env_table[env->name]);
- if (env->implicit || env->allflag)
- pfound = (size > *logtarget);
- else if ((my_set->bitmap[*logtarget]) && (size > *logtarget))
- pfound = TRUE;
- if (!pfound && (neigh>1))
- pfound=D_parent(*parent,neigh,parent,
- logtarget,my_set,env,size);
- }
- return pfound;
- }
- D_cube_stack(next_child,target,p,logtarget,my_set,env,size,start)
- int next_child,target,*p,*logtarget;
- D_env_set *my_set;
- D_env_set *env;
- int size,start;
- {
- int c,ind;
- for(c=start/2; c>0; c>>=1){
- ind=target^c;
- if (!D_parent(ind, next_child<<1,
- p, logtarget, my_set, env,size))
- D_route_stack[ind] = TRUE;
- else if(*logtarget==D_my_env.index)
- D_route_stack[ind] = TRUE;
- if (c > 1) D_cube_stack(next_child,ind,p,logtarget,my_set,env,size,c);
- }
- return;
- }
-
-
-
- /* D_route_cube_init
- *
- * Purpose : initialize cube routing
- *
- * Input : env - pointer to an envset(s)
- *
- * Output :
- */
- D_route_cube_init(env)
- D_env_set *env;
- {
- int i;
- int high_bit, maxsize;
-
- for (i=0; (i<env->count) && (env[i].name != D_my_env.name); i++);
- my_set = (env[i].name != D_my_env.name)? NULL : &env[i];
- crnt_set = (env->name == D_my_env.name)
- ? (env->count == 1
- ? NULL
- : &env[1])
- : env;
- crnt_index = (env->name == D_my_env.name)
- ? (env->count == 1
- ? 0
- : 1)
- : 0;
- if (my_set == NULL)
- return;
-
- my_gray = D_gray(D_my_env.index, &D_env_table[D_my_env.name]);
- size = D_env_table[D_my_env.name].size;
- high_bit = D_high_bit(size);
- is_simple_cube = ((high_bit ^ size) == 0) && my_set->implicit; /*power of 2*/
-
- maxsize=0;
- for (i=0;i<env->count;i++)
- if (D_env_table[env[i].name].size > maxsize)
- maxsize=D_env_table[env[i].name].size;
- maxstep=D_high_bit(maxsize);
- maxstep=(maxsize & ~maxstep)?(maxstep<<1):maxstep;
- maxstep=which_bit(maxstep);
- done_size=size;
-
-
- if (!is_simple_cube)
- {
- register int i,count;
- register int high;
- int maxone=0;
- done_size=0;
-
- if (!(my_set->implicit))
- {
- for (i=0;i<size;i++)
- if(my_set->bitmap[i]){
- done_size++;
- maxone=i+1;
- }
- size = D_min(size,maxone);
- if (size < (2 * done_size)) done_size=size;
- }
- else done_size=size;
-
- high = (high_bit ^ size) == 0 ? high_bit : high_bit << /*+*/ 1;
- for (i=0; i< high; i++)
- D_route_stack[i] = 0;
- is_stack_empty = TRUE;
- if (my_set->implicit || my_set->allflag)
- count = size;
- else for (i=count=0; i<size && count <2; i++)
- count += my_set->bitmap[i];
- done_me = (count < 2);
- }
- else done_me = done_size == 1;
- child.name = D_my_env.name;
- next_child = 1;
- bit = 0;
- if (my_set -> implicit || my_set -> allflag)
- my_root = 0;
- else {
- register char *i,*s;
- for (i=my_set->bitmap, s=(char *)&my_set->bitmap[size]; (i<s)&& !*i; i++);
- my_root = i-my_set->bitmap;
- }
- }
-
-
- /* D_route_cube
- *
- * Purpose : cube routing
- *
- * Input : env - pointer to an envset(s)
- *
- * Output : done set if no more partners
- * tree set to bitmap if value must be sent to a group
- * type describes who goes where:
- * D_route_pair : send and recv from the returned envvar
- * D_route_rcvsnd : receive from the envvar, send to tree bitmap
- * if tree is null then send to all
- * D_route_recv : receive from returned envvar
- */
- envvar *D_route_cube(env,done,tree,type,bitpt)
- D_env_set *env;
- D_BOOL *done;
- D_BOOL **tree;
- D_route_type *type;
- int *bitpt;
- {
- D_BOOL setbit = TRUE;
-
- if(!done_me)
- if (is_simple_cube)
- then {
- child.index = D_ginv(my_gray ^ next_child,
- &D_env_table[env->name]);
- next_child <<= 1;
- *bitpt = bit++;
- done_me = next_child >= done_size;
- *tree = NULL;
- *type = D_route_pair;
- }
- else {
- D_BOOL found = FALSE;
- int target, logtarget;
-
- while (!found /* && (next_child < size) */ ){ /*find recv*/
- setbit = TRUE;
- target = my_gray ^ next_child;
- logtarget = D_ginv(target,&D_env_table[env->name]);
- if ( !env->implicit && !env->allflag && (!my_set->bitmap[logtarget] || size < logtarget)) setbit=FALSE;
-
- if ((logtarget <size) ? /*this is a valid point in envset*/
- ((env->implicit || env->allflag)
- ? TRUE : my_set->bitmap[logtarget]):
- FALSE)
- then {
- found = TRUE;
- *type = D_route_pair;
- }
- else {
- int parent, pfound;
-
- pfound = D_parent(target, next_child,
- &parent, &logtarget, my_set, env,size);
- if ((!pfound) || (parent^target) >= next_child)
- then {
- int p,c;
-
- is_stack_empty = FALSE;
- D_route_stack[target] = TRUE;
- D_cube_stack(next_child,target,&p,&logtarget,
- my_set,env,size,next_child);
- next_child <<=1;
- *bitpt = bit++;
- *type = D_route_rcvsnd;
- }
- else {
- found = TRUE;
- *type = D_route_recv;
- }
- target = parent;
- }
- }
- if (is_stack_empty)
- then{
- child.index = logtarget;
- next_child <<= 1;
- *bitpt = bit++;
- *tree = 0;
- }
- else {
- register int i,in,lin,high,high_bit;
-
- child.index = logtarget;
- for (i=0; i<size; i++)
- D_route_tree_map[i]=0;
- high_bit = D_high_bit(size);
- high = (high_bit ^ size) == 0 ? high_bit : high_bit<</*+*/1;
- /* for (i=0; i<size; i++){ */
- for (i=0; i<high; i++){
- if (D_route_stack[i])
- {
- in = i ^ next_child;
- lin = D_ginv(in,&D_env_table[env->name]);
- D_route_tree_map[lin] =
- ( lin < size && ( my_set->implicit || my_set -> allflag)) ?
- 1 :
- my_set->bitmap[lin] && lin < size;
- }
- }
-
- if (setbit)
- D_route_tree_map[logtarget] = 1; /*add this child */
- *tree = D_route_tree_map;
- *type = D_route_rcvsnd;
- next_child <<= 1;
- *bitpt = bit++;
- }
- done_me = next_child >= done_size;
- *done = done_me && (env->count==1);
- return &child;
- }
- else if (crnt_set != NULL){
- child.name = crnt_set->name;
- if (crnt_set -> implicit || crnt_set -> allflag)
- then child.index = 0;
- else {
- register D_BOOL *i, *s;
- for(i=crnt_set->bitmap,
- s=(D_BOOL *)&(crnt_set->bitmap[D_env_table[crnt_set->name].size]);
- i<s && !*i; i++);
- child.index = D_ginv(i-crnt_set->bitmap,&D_env_table[env->name]);
- };
- if (my_root == my_gray)
- then {
- *type = D_route_rcvsnd;
- *tree = (crnt_set -> implicit || crnt_set->allflag)
- ? NULL
- : crnt_set->bitmap;
- *bitpt=maxstep;
- }
- else *type = D_route_recv;
- crnt_index++;
- if ((crnt_index >= env->count) ||
- ((my_set->name == env[crnt_index].name) && (crnt_set==env)))
- then crnt_set = NULL;
- else if(my_set->name == env[crnt_index].name)
- then crnt_set+=2;
- else crnt_set++;
- }
- *done = done_me && (crnt_set == NULL);
- return &child;
- }
-
-
-